package com.wash.framework.web.ctrl;

import org.springframework.util.ClassUtils;
import org.springframework.web.servlet.mvc.support.AbstractControllerUrlHandlerMapping;

import com.wash.ctrl.cart.ShoppingCartCtrl;
import com.wash.framework.utils.StringUtils;

public class ControllerClassNameHandlerMapping extends AbstractControllerUrlHandlerMapping{

	private boolean caseSensitive = true;

	private String[] frameworkPackagePrefixs ={ "com.wash.ctrl." };

	private String[] actionClassSuffixs={ "Ctrl,Controller" };

	private String[] actionPackageSuffixs={ "ctrl" };
	private String pathPrefix;
	private String basePackage;

	@Override
	protected String[] buildUrlsForHandler(String beanName, Class beanClass) {
		return generatePathMappings(beanClass);
	}
	
	public static void main(String[] args) {
		String[] a=new ControllerClassNameHandlerMapping().buildUrlsForHandler("shoppingCartCtrl", ShoppingCartCtrl.class);
		for(String s:a){
			System.out.println(s);
		}
		
	}
	
	public String[] getFrameworkPackagePrefixs() {
		return this.frameworkPackagePrefixs;
	}

	public void setFrameworkPackagePrefixs(String[] frameworkPackagePrefixs) {
		this.frameworkPackagePrefixs = frameworkPackagePrefixs;
		for (int i = 0; i < this.frameworkPackagePrefixs.length; i++) {
			String frameworkPackagePrefix = frameworkPackagePrefixs[i];
			if ((StringUtils.hasLength(frameworkPackagePrefix))
					&& (!frameworkPackagePrefix.endsWith("."))) {
				frameworkPackagePrefix = new StringBuilder()
						.append(frameworkPackagePrefix).append(".").toString();
			}
			frameworkPackagePrefixs[i] = frameworkPackagePrefix;
		}
	}

	public void setActionClassSuffixs(String[] actionClassSuffixs) {
		this.actionClassSuffixs = actionClassSuffixs;
	}

	public String[] getActionClassSuffixs() {
		return this.actionClassSuffixs;
	}

	public void setActionPackageSuffixs(String[] actionPackageSuffixs) {
		for (int i = 0; i < actionPackageSuffixs.length; i++) {
			String actionPackageSuffix = actionPackageSuffixs[i];
			if ((StringUtils.hasLength(actionPackageSuffix))
					&& (!actionPackageSuffix.startsWith("."))) {
				actionPackageSuffixs[i] = new StringBuilder().append(".")
						.append(actionPackageSuffix).toString();
			}
		}
		this.actionPackageSuffixs = actionPackageSuffixs;
	}

	public String[] getActionPackageSuffixs() {
		return this.actionPackageSuffixs;
	}

	public void setCaseSensitive(boolean caseSensitive) {
		this.caseSensitive = caseSensitive;
	}

	public final boolean isCaseSensitive() {
		return this.caseSensitive;
	}

	public void setPathPrefix(String prefixPath) {
		this.pathPrefix = prefixPath;
		if (StringUtils.hasLength(this.pathPrefix)) {
			if (!this.pathPrefix.startsWith("/")) {
				this.pathPrefix = new StringBuilder().append("/")
						.append(this.pathPrefix).toString();
			}
			if (this.pathPrefix.endsWith("/"))
				this.pathPrefix = this.pathPrefix.substring(0,
						this.pathPrefix.length() - 1);
		}
	}

	public void setBasePackage(String basePackage) {
		this.basePackage = basePackage;
		if ((StringUtils.hasLength(this.basePackage))
				&& (!this.basePackage.endsWith(".")))
			this.basePackage = new StringBuilder().append(this.basePackage)
					.append(".").toString();
	}

	

	protected String[] generatePathMappings(Class beanClass) {
		StringBuilder pathMapping = buildPathPrefix(beanClass);
		String className = ClassUtils.getShortName(beanClass);
		String path = getEndWithSuffixPath(className, this.actionClassSuffixs);
		if (path.length() > 0) {
			if (this.caseSensitive) {
				pathMapping.append(path.substring(0, 1).toLowerCase()).append(
						path.substring(1));
			} else {
				pathMapping.append(path.toLowerCase());
			}
		}
		if (isMultiActionControllerType(beanClass)) {
			return new String[] {
					pathMapping.toString(),
					new StringBuilder().append(pathMapping.toString())
							.append("/*").toString() };
		}
		return new String[] { new StringBuilder()
				.append(pathMapping.toString()).append("*").toString() };
	}

	private String getEndWithSuffixPath(String className, String[] suffixs) {
		String path = "";
		for (String suffix : suffixs) {
			if (className.endsWith(suffix)) {
				path = className.substring(0, className.lastIndexOf(suffix));
				break;
			}
		}
		return StringUtils.isEmpty(path) ? className : path;
	}

	private StringBuilder buildPathPrefix(Class beanClass) {
		StringBuilder pathMapping = new StringBuilder();
		if (this.pathPrefix != null) {
			pathMapping.append(this.pathPrefix);
			pathMapping.append("/");
		} else {
			pathMapping.append("/");
		}
		if (this.basePackage != null) {
			String packageName = ClassUtils.getPackageName(beanClass);
			if (packageName.startsWith(this.basePackage)) {
				String subPackage = packageName.substring(
						this.basePackage.length()).replace('.', '/');
				pathMapping.append(this.caseSensitive ? subPackage : subPackage
						.toLowerCase());
				pathMapping.append("/");
			}
		} else {
			pathMapping.append(StringUtils.buildPathByBeanClass(beanClass,
					this.frameworkPackagePrefixs, this.actionPackageSuffixs,
					this.caseSensitive));
		}
		return pathMapping;
	}
}
